package com.aisafer.fms.action;

import java.io.BufferedOutputStream;
import java.io.IOException;
import java.io.OutputStream;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.apache.commons.io.IOUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.multipart.MultipartFile;
import org.springframework.web.multipart.MultipartHttpServletRequest;

import com.aisafer.base.enums.ResponseEnum;
import com.aisafer.base.pojo.Response;
import com.aisafer.fms.client.dto.AttachmentContent;
import com.aisafer.fms.client.dto.AttachmentReq;
import com.aisafer.fms.client.dto.AttachmentResp;
import com.aisafer.fms.client.dto.AttachmentUploadReq;
import com.aisafer.fms.client.dto.DownReq;
import com.aisafer.fms.client.dto.DownResp;
import com.aisafer.fms.client.service.AttachmentService;
import com.aisafer.fms.mapper.AttachmentMapper;
import com.aisafer.fms.service.impl.ModuleService;
import com.aisafer.fms.utils.Base64;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;

/**
 * 没有加密的文件信息
 */
@RestController
@RequestMapping("/attach")
public class AttachmentAction {
	private static Logger logger = LoggerFactory.getLogger(AttachmentAction.class);

	@Autowired
	private AttachmentService attachmentService;

	@Autowired
	ModuleService moduleService;
	
	
	@Autowired
	AttachmentMapper attachmentMapper;
	

	@RequestMapping(value = "/upload/v1/", method = { RequestMethod.POST, RequestMethod.GET })
	@ResponseBody
	public String uploadfile(HttpServletRequest request, HttpServletResponse response, AttachmentUploadReq req) {
		return saveFileMultipart(request, response, req);
	}

	@RequestMapping(value = "/base64/v1/", method = { RequestMethod.POST, RequestMethod.GET })
	@ResponseBody
	public String download(HttpServletRequest request, HttpServletResponse response, DownReq down)
			throws JsonProcessingException {
		ObjectMapper om = new ObjectMapper();
		try {
			long beginTime = System.currentTimeMillis();
			byte[] content = attachmentService.downloadFileByte(down);
			logger.info("downLoad.time:{}", (System.currentTimeMillis() - beginTime));
			response.setContentType("text/html");
			response.setCharacterEncoding("utf-8");
			return Base64.encode(content);
		} catch (Exception e) {
			logger.error(e.getMessage(), e);
			Response<String> res = new Response<String>();
			res.setCode(ResponseEnum.FAILURE5010.getCode());
			res.setMsg(ResponseEnum.FAILURE5010.getMessage());
			logger.error(om.writeValueAsString(res));
			return om.writeValueAsString(res);
		}
	}

	@RequestMapping(value = "/byte/v1/", method = { RequestMethod.POST, RequestMethod.GET })
	@ResponseBody
	public byte[] downloadbyte(HttpServletRequest request, HttpServletResponse response, DownReq down) {
		try {
			long beginTime = System.currentTimeMillis();
			byte[] content = attachmentService.downloadFileByte(down);
			logger.info("downLoadbyte.time:{}", (System.currentTimeMillis() - beginTime));
			return content;
		} catch (Exception e) {
			logger.error(e.getMessage(), e);
		}
		return null;
	}
	

	@RequestMapping(value = "/download/v1/", method = { RequestMethod.POST, RequestMethod.GET })
	@ResponseBody
	public void downloadfile(HttpServletRequest request, HttpServletResponse response, DownReq down) {
		try {
			long beginTime = System.currentTimeMillis();
			down(response, down);
			logger.info("downloadfile.time:{}", (System.currentTimeMillis() - beginTime));
		} catch (Exception e) {
			logger.error(e.getMessage(), e);
		}
	}

	private void down(HttpServletResponse response, DownReq down) throws IOException {
		DownResp resp = attachmentService.download(down);
		if(resp == null || resp.getContent() == null) {
			return;
		}
		response.reset();
		response.setHeader("Content-Disposition", "attachment; filename=\"" +String.valueOf(System.currentTimeMillis()) + resp.getFileType() + "\"");
		response.addHeader("Content-Length", "" + resp.getContent().length);
		response.setContentType("application/octet-stream;charset=UTF-8");
		OutputStream outputStream = new BufferedOutputStream(response.getOutputStream());
		outputStream.write(resp.getContent());
		outputStream.flush();
		outputStream.close();
	}


	@RequestMapping(value = "/view/v1/", method = { RequestMethod.POST, RequestMethod.GET })
	@ResponseBody
	public void view(HttpServletRequest request, HttpServletResponse response, DownReq down) {
		
		try {
			long beginTime = System.currentTimeMillis();
			view(response, down, beginTime);
		} catch (Exception e) {
			logger.error(e.getMessage(), e);
		}
	}
	

	private void view(HttpServletResponse response, DownReq down, long beginTime) throws IOException {
		OutputStream os = null;
		try {
			byte[] content = attachmentService.downloadFileByte(down);
			logger.info("view.time:{}", (System.currentTimeMillis() - beginTime));
			if(content == null) {
				return;
			}
			
			os = response.getOutputStream();
				os.write(content);
		} catch (Exception e) {
			logger.error(e.getMessage(), e);
		}finally {
			IOUtils.closeQuietly(os);
		}
	}

	private String saveFileMultipart(HttpServletRequest request, HttpServletResponse response,
			AttachmentUploadReq uploadParm) {
		ObjectMapper om = new ObjectMapper();
		try {
			MultipartHttpServletRequest mulReq = (MultipartHttpServletRequest) request;
			MultipartFile file = mulReq.getFile("file");
			AttachmentReq req = new AttachmentReq();
			AttachmentContent attachmentContent = new AttachmentContent();
			req.setModuleKey(uploadParm.getModuleKey());
			attachmentContent = new AttachmentContent();
			attachmentContent.setContent(file !=null ? file.getBytes() : new byte[] {});
			attachmentContent.setFileSize(Integer.valueOf(attachmentContent.getContent().length).longValue());
			attachmentContent.setFileType(uploadParm.getFileType());
			attachmentContent.setFileName(uploadParm.getFileName());
			attachmentContent.setSourceCode(uploadParm.getSourceCode());
			req.setAttachmentContent(attachmentContent);
			Response<AttachmentResp> result = attachmentService.uploadFile(req);
			// RequestUtils.out(response, JSONUtil.toJson(result));
			return om.writeValueAsString(result);
		} catch (Exception e) {
			logger.error(e.getMessage(), e);
			Response<String> res = new Response<String>();
			res.setCode(ResponseEnum.FAILURE5010.getCode());
			res.setMsg(ResponseEnum.FAILURE5010.getMessage());
			try {
				logger.error(om.writeValueAsString(res));
				return om.writeValueAsString(res);
			} catch (JsonProcessingException e1) {
				e1.printStackTrace();
			}
		}
		return null;
	}
}
